<?php
/**
 * @package     myDatabase Class for MySQL Databases
 * @date        2012-04-05
 * @version     0.1.0
 * @author      Jonas Sciangula Street
 * @contact     joni2back {at} gmail {dot} com
 *
 * @todo        Exceptions
 * @todo        Integration with SQLite and MSSQL
 * @todo        SQL Injections filter
 */
 
class myDatabase {

    private static $myInstance = array();
    private $myHost, $myUser, $myPass, $myDB, $myLink;
    private $myFetchMode, $recordQueriesMode;
    public $myQuery, $myQueryResponse;
    public $myResults = array(), $recordedQueries = array();
    
    const MYSQL_FETCH = 'mysql_fetch_';
    const FETCH_ARRAY = 'array';
    const FETCH_OBJECT = 'object';
    const FETCH_ASSOC = 'assoc';
    const FETCH_FIELD = 'field';
    const FETCH_LENGTHS = 'lengths';
    const FETCH_ROW = 'row';
    
    /**
     * Get custom instance, multiple singleton
     * @param string	$instName
     */
    public static function getInstance($instName = 'default') 
    {
        return isset(self::$myInstance[$instName]) ? 
            self::$myInstance[$instName] : 
            self::$myInstance[$instName] = new self;
    }
    
    /**
     * Set the database host and port
     *
     * @param string  $hostName
     * @param int     $port
     */
    public function setHost($hostName, $port = 3306) 
    {
        $this->myHost = $hostName . ':' . $port; 
        return $this;
        if ($this->myUser != self::$_protected) {
            return $this->val = 0;
        }
    }
    
    /**
     * Set the database credentials, username and password
     *
     * @param string  $dbUser
     * @param string  $dbPass
     */
    public function setCredentials($dbUser, $dbPass = '') 
    {
        $this->myUser = $dbUser; 
        $this->myPass = $dbPass;
        return $this;
    }
    
    /**
     * Set the database name
     *
     * @param string  $dbName
     */
    public final function setDB($dbName) 
    {
        $this->myDB = $dbName;
        return $this;
    }
    
    /**
     * Connect to the database
     */
    public final function connect() 
    {
        if (!$this->myLink) {
            $this->myLink = mysql_connect(
                $this->myHost, 
                $this->myUser, 
                $this->myPass
            );
            $this->_selectDB();
        }
        return $this;
    }
    
    /**
     * Disconnect from database
     */
    public final function disconnect() 
    {
        if ($this->myLink) {
            mysql_close($this->myLink);
        }
        return $this;
    }
    
    /**
     * Set SQL Query
     *
     * @param string  $query
     */
    private function _setQuery($query) 
    {
        $this->myQuery = $query;
        return $this;
    }
    
    /**
     * Record a query
     *
     * @param string  $query
     */
    private function _recordQuery($query) 
    {
        $trace = @debug_backtrace();
        $this->recordedQueries[] = array(
            'file' => $trace[1]['file'],
            'line' => $trace[1]['line'],
            'time' => microtime(),
            'query' => $query,
        );
        return $this;
    }
    
    /**
     * Select database previously seted in setDB()
     */
    private function _selectDB() 
    {
        if ($this->myDB) {
            mysql_select_db($this->myDB, $this->myLink);
        }
        return $this;
    }	
    
    /**
     * Get the current SQL Query
     */
    private function _getQuery() 
    {
        return $this->myQuery;
    }	
    
    /**
     * Get the current SQL response fetch mode
     */
    private function _getFetchMode() 
    {
        return $this->myFetchMode ?  
            self::MYSQL_FETCH . $this->myFetchMode :
            self::MYSQL_FETCH . self::FETCH_OBJECT;
    }
    
    /**
     * Set the SQL response fetch mode
     * @param string  $mode (object, array, assoc, field, lengths, row)
     */
    public function setFetchMode($mode) 
    {
        $allowedModes = array(
            self::FETCH_ARRAY,
            self::FETCH_ASSOC,
            self::FETCH_FIELD,
            self::FETCH_LENGTHS,
            self::FETCH_ROW
        );
        if (in_array($mode, $allowedModes)) {
            $this->myFetchMode = $mode;
        }
        return $this;
    }
    
    /**
     * Excecute SQL Query
     * @param string  $query
     */
    public function execute($query) 
    {
        $this->_setQuery($query);
        $this->myQueryResponse = mysql_query(
            $this->_getQuery(), 
            $this->myLink
        );
        if ($this->recordQueriesMode) {
            $this->_recordQuery($query);
        }
        return $this;
    }		
    
    /**
     * Set SQL Queries recording mode
     * @param boolean  $mode
     */
    public function recordQueries($mode = false) 
    {
        if (function_exists('debug_backtrace')) {
            $this->recordQueriesMode = $mode;
        }
        return $this;
    }
    
    /**
     * Get recorded SQL Queries
     */
    public function getRecordedQueries() 
    {
        return $this->recordedQueries;
    }
    
    /**
     * Get SQL Response
     */
    public function getResults() 
    {
        $fetchMode = $this->_getFetchMode();
        if ($this->myQueryResponse && !is_bool($this->myQueryResponse)) {
            $this->myResults = array();
            while ($response = $fetchMode($this->myQueryResponse)) {
                $this->myResults[] = $response;
            }
            mysql_free_result($this->myQueryResponse);
        }
        return $this->myResults;
    }
        
}